﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Cinchoo.Core;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

namespace Cinchoo.Core.Configuration
{
    public class ChoConfigStorageJSONPayloadSerializer : IChoConfigStoragePayloadSerializer
    {
        internal readonly static ChoConfigStorageJSONPayloadSerializer Instance = new ChoConfigStorageJSONPayloadSerializer();

        public Dictionary<string, object> Deserialize(object payload)
        {
            if (payload == null || !(payload is string)) return null;

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(StringStringDictionary));
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(payload as string)))
            {
                StringStringDictionary dict = (StringStringDictionary)ser.ReadObject(ms);
                return dict.UnderlyingDict;
            }
        }

        public object Serialize(Dictionary<string, object> target)
        {
            if (target == null) return null;

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(StringStringDictionary));
            using (MemoryStream ms = new MemoryStream())
            {
                ser.WriteObject(ms, new StringStringDictionary(target));
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }
    }

    [Serializable]
    public class StringStringDictionary : ISerializable
    {
        public Dictionary<string, object> UnderlyingDict;

        public StringStringDictionary(Dictionary<string, object> dict = null)
        {
            UnderlyingDict = dict ?? new Dictionary<string, object>();
        }

        protected StringStringDictionary(SerializationInfo info, StreamingContext context)
        {
            UnderlyingDict = new Dictionary<string, object>();
            foreach (SerializationEntry entry in info)
            {
                UnderlyingDict.Add(entry.Name, (string)entry.Value);
            }
        }
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            foreach (string key in UnderlyingDict.Keys)
            {
                info.AddValue(key, UnderlyingDict[key]);
            }
        }
    }
}